#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#define N 3

/* date struct */

typedef struct
{
    int year;
    int month;
    int day;
}Date;

/* student struct */

typedef struct
{
    int ID;
    char *name;
    char *gender;
    Date birthday;
}Stu, *StuPt;

/* function protypes */

/* Array traversal */

void Traversal(StuPt, int, void(*)(StuPt));
void Input(StuPt);
void Output(StuPt);
void Destroy(StuPt);
bool InitStu(StuPt, int, const char*, const char*, int, int, int);
bool CopyStu(StuPt, StuPt);
int ReadLine(char*, int);

int main(void)
{
    Stu stu[N] = {0};
    FILE *pf = freopen("data.txt", "r", stdin);
    if (pf == NULL)
    {
        printf("File Open Error!\n");
        exit(1);
    }
    else
    {
        printf("File Open Ok!\n");
    }
    Traversal(stu, N, Input);
    freopen("CON", "r", stdin);
    Traversal(stu, N, Output);
    printf("\n");

    Traversal(stu, N, Destroy);

    return 0;
}

void Traversal(StuPt ps, int n, void(*pf)(StuPt))
{
    StuPt p;

    for(p = ps; p < ps + n; p ++)
    {
        pf(p);
    }
}

void Input(StuPt ps)
{
    int id;
    char name[81], gender[15];
    int year, month, day;

    scanf("%d", &id);
    // skip other infor and '\n'
    while (getchar() != '\n')
        ;

    ReadLine(name, 81);
    ReadLine(gender, 15);

    scanf("%d%d%d", &year, &month, &day);

    InitStu(ps, id, name, gender, year, month, day);

}

void Output(StuPt ps)
{
    printf("%d\t%s\t%s\t%d/%d/%d\n", ps->ID, 
            ps->name, ps->gender, ps->birthday.year,
            ps->birthday.month, ps->birthday.day);
}

bool InitStu(StuPt ps, int id, const char *pname, const char *pgender, int year,
        int month, int day)
{
    if (ps == NULL || pname == NULL || pgender == NULL)
    {
        return false;
    }

    ps->ID = id;
    
    ps->name = (char*)malloc((strlen(pname) + 1) * sizeof(char));
    ps->gender = (char*)malloc((strlen(pgender) + 1) * sizeof(char));

    if (ps->name == NULL || ps->gender == NULL)
    {
        ps->ID = -1;
        return false;
    }

    strcpy(ps->name, pname);
    ps->name[strlen(ps->name)-1] = '\0';
    strcpy(ps->gender, pgender);
    ps->gender[strlen(ps->gender)-1] = '\0';

    ps->birthday.year = year;
    ps->birthday.month = month;
    ps->birthday.day = day;

    return true;
}

bool CopyStu(StuPt psTo, StuPt psFrom)
{
    if (psFrom == NULL || psFrom->gender == NULL || psFrom->name == NULL ||
            psTo == NULL)
    {
        return false;
    }

    if (psTo->name != NULL)
    {
        free(psTo->name);
    }

    if (psTo->gender != NULL)
    {
        free(psTo->gender);
    }

    psTo->name = (char*)malloc(sizeof(char) * (strlen(psFrom->name) + 1));
    psTo->gender = (char*)malloc(sizeof(char) * (strlen(psFrom->gender) + 1));

    if (psTo->name == NULL || psTo->gender == NULL)
    {
        psTo->ID = 1;
        return false;
    }

    psTo->ID = psFrom->ID;
    strcpy(psTo->name, psFrom->name);
    strcpy(psTo->gender, psFrom->gender);
    psTo->birthday.year = psFrom->birthday.year;
    psTo->birthday.month = psFrom->birthday.month;
    psTo->birthday.day = psFrom->birthday.day;

    return true;
}

int ReadLine(char *pLine, int n)
{
    char *ps = fgets(pLine, n, stdin); /* fgets will append '\0' at the end of the string. The '\n' read is kept as well. */

    return strlen(ps);
}

void Destroy(StuPt ps)
{
    free(ps->name);
    ps->name = NULL;
    free(ps->gender);
    ps->gender = NULL;
}


















